import VectorSource from 'ol/source/Vector'
import Feature from 'ol/Feature'
import LineString from 'ol/geom/LineString'
import Point from 'ol/geom/Point'
import { Style, Stroke, Circle, Fill } from 'ol/style'
import { fromLonLat } from 'ol/proj'

interface AnimationOptions {
  animationSpeed?: number
  pointStyle?: Style
  lineStyle?: Style
}

const defaultPointStyle = new Style({
  image: new Circle({
    radius: 6,
    fill: new Fill({
      color: '#00eaff'
    }),
    stroke: new Stroke({
      color: '#ffffff',
      width: 2
    })
  })
})

const defaultLineStyle = new Style({
  stroke: new Stroke({
    color: 'rgba(0, 234, 255, 0.8)',
    width: 3,
    lineCap: 'round',
    lineJoin: 'round'
  })
})

export class PathAnimation {
  private vectorSource: VectorSource
  private animationFrameId: number | null = null
  private currentIndex: number = 0
  private points: number[][] = []
  private lastUpdateTime: number = 0
  private options: AnimationOptions
  private isAnimating: boolean = false
  private isLooping: boolean = false

  constructor(vectorSource: VectorSource, options: AnimationOptions = {}) {
    this.vectorSource = vectorSource
    this.options = {
      animationSpeed: options.animationSpeed || 50,
      pointStyle: options.pointStyle || defaultPointStyle,
      lineStyle: options.lineStyle || defaultLineStyle
    }
  }

  private updateAnimation(timestamp: number) {
    if (!this.isAnimating) return

    if (timestamp - this.lastUpdateTime < this.options.animationSpeed!) {
      this.animationFrameId = requestAnimationFrame(this.updateAnimation.bind(this))
      return
    }
    this.lastUpdateTime = timestamp

    if (this.currentIndex < this.points.length) {
      // 创建新的点
      const point = new Feature({
        geometry: new Point(fromLonLat(this.points[this.currentIndex]))
      })
      point.setStyle(this.options.pointStyle)
      this.vectorSource.addFeature(point)

      // 如果至少有两个点，绘制线段
      if (this.currentIndex > 0) {
        const line = new Feature({
          geometry: new LineString([
            fromLonLat(this.points[this.currentIndex - 1]),
            fromLonLat(this.points[this.currentIndex])
          ])
        })
        line.setStyle(this.options.lineStyle)
        this.vectorSource.addFeature(line)
      }

      this.currentIndex++
    } else {
      // 动画完成
      if (this.isLooping) {
        // 如果是循环模式，重置并继续
        this.currentIndex = 0
        this.vectorSource.clear()
      } else {
        // 非循环模式，停止动画
        this.stop()
      }
    }

    this.animationFrameId = requestAnimationFrame(this.updateAnimation.bind(this))
  }

  public start(geojson: any, loop: boolean = false) {
    if (!geojson?.features?.length) {
      console.error('无效的 GeoJSON 数据')
      return
    }

    // 提取所有坐标点
    this.points = geojson.features.flatMap((f: any) => f.geometry.coordinates)
    
    // 重置状态
    this.currentIndex = 0
    this.vectorSource.clear()
    this.isAnimating = true
    this.isLooping = loop
    
    // 开始动画
    this.animationFrameId = requestAnimationFrame(this.updateAnimation.bind(this))
  }

  public stop() {
    this.isAnimating = false
    this.isLooping = false
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId)
      this.animationFrameId = null
    }
  }

  public destroy() {
    this.stop()
    this.vectorSource.clear()
  }
} 